{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install -U git+https://github.com/qubvel/efficientnet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "__file__ = 'EfficientNet-B5-9.7.3-0123'\n",
    "__version__ = 'v11'\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0,1,2,3\"\n",
    "fold = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from glob import glob\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import keras\n",
    "from keras.applications.inception_v3 import InceptionV3\n",
    "from keras.applications.xception import Xception\n",
    "from keras.applications.resnet50 import ResNet50\n",
    "from keras_applications.resnext import ResNeXt50\n",
    "from keras.applications.nasnet import NASNetLarge\n",
    "from keras.applications.inception_resnet_v2 import InceptionResNetV2\n",
    "from keras.models import *\n",
    "from keras.layers import *\n",
    "from keras.optimizers import *\n",
    "from keras.callbacks import *\n",
    "import PIL\n",
    "import time\n",
    "import efficientnet.keras as efn "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "path_data_train = '../tmp/train_data_aug/'\n",
    "path_data_valid = '../garbage_classify/train_data_v2/'\n",
    "batch_size = 64\n",
    "img_size = 456\n",
    "img_width = img_size\n",
    "img_height = img_size\n",
    "random_seed = 201908"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f3ca46dfd68>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "labels_train = pd.read_csv(f'../tmp/labels_train_aug_{__version__}_fold{fold}.csv')\n",
    "labels_valid = pd.read_csv(f'../tmp/labels_valid_{__version__}_fold{fold}.csv')\n",
    "n_classess = labels_train.label.unique().shape[0]\n",
    "labels_train.groupby(by='label').count().plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "special = [True, False, False, False, False, False, False, False,  True,\n",
    "             True, False, False, False, False,  True,  True,  True, False,\n",
    "             False, False, False, False,  True,  True, False, False, False,\n",
    "             False, False, False, False,  True,  True,  True, False, False,\n",
    "             True, False, False, False]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "n_samples = 1500\n",
    "\n",
    "lbs = []\n",
    "for lb in range(40):\n",
    "    lbs_df = labels_train[labels_train.label==lb]\n",
    "    if lbs_df.shape[0] > n_samples:\n",
    "        if special[lb]:\n",
    "            lbs_df = lbs_df.sample(n=n_samples,random_state=random_seed)\n",
    "        else:\n",
    "            lbs_df = lbs_df.sample(n=1,random_state=random_seed)\n",
    "    lbs.append(lbs_df)\n",
    "lbs_train = pd.concat(lbs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f3ca3b33940>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "lbs_train.groupby(by='label').count().plot(style='-o')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# labels_train.label = labels_train.label.apply(lambda x: f'{x:02d}')\n",
    "lbs_train.label = lbs_train.label.apply(lambda x: f'{x:02d}')\n",
    "labels_valid.label = labels_valid.label.apply(lambda x: f'{x:02d}')\n",
    "# labels_train['label_bin'].values = keras.utils.np_utils.to_categorical(\n",
    "#     labels_train.label, n_classess)\n",
    "\n",
    "# labels_train.label = labels_train.label.apply(int)\n",
    "# labels_valid.label = labels_valid.label.apply(int)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 18764 validated image filenames belonging to 40 classes.\n",
      "Found 2944 validated image filenames belonging to 40 classes.\n"
     ]
    }
   ],
   "source": [
    "ig = ImageDataGenerator(preprocessing_function=efn.preprocess_input,\n",
    "                        horizontal_flip=True,\n",
    "                        vertical_flip=True)\n",
    "\n",
    "params_g = dict(\n",
    "    batch_size=batch_size,\n",
    "    # directory=path_data,\n",
    "    # class_mode='other',\n",
    "    x_col='fname',\n",
    "    y_col='label',\n",
    "    target_size=(img_width, img_height),\n",
    "    interpolation='lanczos',\n",
    "    seed=random_seed)\n",
    "\n",
    "train_g = ig.flow_from_dataframe(lbs_train, path_data_train, **params_g)\n",
    "valid_g = ig.flow_from_dataframe(labels_valid[:-(labels_valid.shape[0] % batch_size)], path_data_valid, shuffle=False, **params_g)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n",
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/function.py:1007: calling Graph.create_op (from tensorflow.python.framework.ops) with compute_shapes is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Shapes are always computed; don't use the compute_shapes as it has no effect.\n",
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n"
     ]
    }
   ],
   "source": [
    "m = ('../tmp/model_EfficientNet-B5-9.5.14-2.json','../tmp/ckpt-EfficientNet-B5-9.5.14-2-Epoch_063-acc_0.99573-val_acc_0.94769.h5')\n",
    "with open(m[0], 'r') as f:\n",
    "    model = model_from_json(f.read())\n",
    "    model.load_weights(m[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.utils import multi_gpu_model\n",
    "model = multi_gpu_model(model,gpus=4)\n",
    "\n",
    "with open(f'../tmp/model_{__file__}.json','w') as f:\n",
    "    model_json = model.to_json()\n",
    "    f.write(model_json)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "ckpt = ModelCheckpoint('../tmp/ckpt-'+__file__+'-Epoch_{epoch:03d}-acc_{acc:.5f}-val_acc_{val_acc:.5f}.h5', save_best_only=True, monitor='val_acc',verbose=1)\n",
    "\n",
    "estop = EarlyStopping(monitor='val_acc', min_delta=1e-7,verbose=1, patience=20)\n",
    "\n",
    "# reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5,patience=2, min_lr=1e-5,verbose=1)\n",
    "\n",
    "csv_logger = CSVLogger(f'../tmp/training_{__file__}.log',append=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n",
      "Epoch 1/100\n",
      "293/293 [==============================] - 571s 2s/step - loss: 0.1476 - acc: 0.9613 - val_loss: 0.2508 - val_acc: 0.9402\n",
      "\n",
      "Epoch 00001: val_acc improved from -inf to 0.94022, saving model to ../tmp/ckpt-EfficientNet-B5-9.7.3-0123-Epoch_001-acc_0.96128-val_acc_0.94022.h5\n",
      "Epoch 2/100\n",
      "293/293 [==============================] - 479s 2s/step - loss: 0.0937 - acc: 0.9753 - val_loss: 0.2586 - val_acc: 0.9423\n",
      "\n",
      "Epoch 00002: val_acc improved from 0.94022 to 0.94226, saving model to ../tmp/ckpt-EfficientNet-B5-9.7.3-0123-Epoch_002-acc_0.97620-val_acc_0.94226.h5\n",
      "Epoch 3/100\n",
      "293/293 [==============================] - 475s 2s/step - loss: 0.0717 - acc: 0.9813 - val_loss: 0.2660 - val_acc: 0.9361\n",
      "\n",
      "Epoch 00003: val_acc did not improve from 0.94226\n",
      "Epoch 4/100\n",
      "293/293 [==============================] - 478s 2s/step - loss: 0.0612 - acc: 0.9833 - val_loss: 0.2810 - val_acc: 0.9321\n",
      "\n",
      "Epoch 00004: val_acc did not improve from 0.94226\n",
      "Epoch 5/100\n",
      "293/293 [==============================] - 478s 2s/step - loss: 0.0573 - acc: 0.9856 - val_loss: 0.2888 - val_acc: 0.9293\n",
      "\n",
      "Epoch 00005: val_acc did not improve from 0.94226\n",
      "Epoch 6/100\n",
      "106/293 [=========>....................] - ETA: 4:18 - loss: 0.0531 - acc: 0.9868"
     ]
    }
   ],
   "source": [
    "model.compile(optimizer=Adam(lr=1e-5), loss='categorical_crossentropy', metrics=['accuracy'])\n",
    "\n",
    "model.fit_generator(\n",
    "    train_g,\n",
    "    # steps_per_epoch=100,\n",
    "    steps_per_epoch=train_g.n // batch_size,\n",
    "    epochs=100,\n",
    "    callbacks=[ckpt, estop,csv_logger],\n",
    "    validation_data=valid_g,\n",
    "    # validation_steps=1,\n",
    "    validation_steps=valid_g.n // batch_size\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!ls"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
